home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / genial / func / common.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-14  |  9.3 KB  |  421 lines

  1. /*
  2.  * common.c -- routines for common operations, i.e. getting a pixel value,
  3.  *             that are used repeatedly
  4.  *
  5.  */
  6.  
  7. #include "ui.h"
  8. #include "display.h"
  9. #include "llist.h"
  10. #include "plist.h"
  11. #include "common.h"
  12. #include "scale.h"
  13. #include <ctype.h>
  14. #include <strings.h>
  15.  
  16. static struct pval prune_buf[4000];    /* buffer of pruned point list. */
  17. static int nprune;
  18.  
  19. /* makepbuf() -- makes a continous pbuf from a linked list of pbstores. This
  20.    is useful for things like traces which have to have interactive access to
  21.    the points which the region is made of */
  22. /* makepbuf() calls prune().  The two of these could very easily be
  23.    combined into one functions and the whole thing would be much more
  24.    efficient if we did that.  FIX THIS!! */
  25.  
  26. int
  27. makepbuf(src, dst)
  28.     struct dlist *src;
  29.     struct pval **dst;
  30. {
  31.     struct dlist *trav;
  32.     struct pval *buf = NULL;
  33.     int       npts = 0;
  34.  
  35.     for (trav = src; trav != NULL; trav = trav->next) {
  36.     if (buf == NULL) {
  37.         buf = (struct pval *) malloc(trav->len * sizeof(struct pval));
  38.     } else {
  39.         buf = (struct pval *) realloc((char *) buf,
  40.                   (npts + trav->len) * sizeof(struct pval));
  41.     }
  42.     bcopy((char *) trav->points, (char *) (buf + npts),
  43.           trav->len * sizeof(struct pval));
  44.     npts += trav->len;
  45.     }
  46.     prune(buf, npts);
  47.     /* now copy the pruned point buffer to dst */
  48.     free(buf);
  49.     buf = (struct pval *) malloc(nprune * sizeof(struct pval));
  50.     bcopy((char *) prune_buf, (char *) buf, nprune * sizeof(struct pval));
  51.     *dst = buf;
  52.     npts = nprune;
  53.     nprune = 0;
  54.     return npts;
  55. }
  56.  
  57. /* prune removes duplicate points which could show up from a spline trace and
  58.    should also get the pixel value off the ORIGINAL image as opposed to the
  59.    image which has been scaled in the appropriate manner for the colormap. */
  60.  
  61. int
  62. prune(plst, npts)
  63.     struct pval *plst;
  64.     int       npts;
  65. {
  66.     struct pval *tr;
  67.     int       s, t, found;
  68.  
  69.     tr = prune_buf + 1;
  70.     bcopy((char *) plst, (char *) prune_buf, sizeof(struct pval));
  71.     for (t = 0; t <= (npts - 4); t++) {
  72.     found = 0;
  73.     for (s = 1; s <= 4; s++) {
  74.         if (plst[t].pt.x == plst[t + s].pt.x && plst[t].pt.y == plst[t + s].pt.y)
  75.         found = 1;
  76.     }
  77.     if (found == 0) {
  78.         bcopy((char *) (&plst[t]), (char *) tr, sizeof(struct pval));
  79.         nprune++;
  80.         tr++;
  81.     }
  82.     }
  83. }
  84.  
  85. /* box_vec() -- build a vector which is the average across of the pixel
  86.  * values in a rectangular region
  87.  */
  88. box_vec(pl, obuf)
  89.     struct plist *pl;
  90.     struct pval **obuf;
  91. {
  92.     int       len, width, orient, x, y, val;
  93.     struct pval *pbuf, *ptmp;
  94.  
  95.     /* compute the direction of the rectangle */
  96.     orient = box_direction(pl);
  97.  
  98.     switch (orient) {
  99.     case HORIZONTAL:
  100.     len = pl->next->pt.x - pl->pt.x;
  101.     width = pl->next->pt.y - pl->pt.y;
  102.     pbuf = (struct pval *) malloc(len * sizeof(struct pval));
  103.     ptmp = pbuf;
  104.     for (x = pl->pt.x; x < pl->next->pt.x; x++) {
  105.         val = 0;
  106.         for (y = pl->pt.y; y < pl->next->pt.y; y++) {
  107.         val += getpix(orig_img, x, y);
  108.         };
  109.         val = val / width;
  110.         /*
  111.          * okay we have computed an average value, lets add it to the
  112.          * point buffer.
  113.          */
  114.         ptmp->pt.x = (short) x;
  115.         ptmp->pt.y = (short) pl->pt.y + width / 2;
  116.         ptmp->val = XGetPixel(orig_ximg, ptmp->pt.x, ptmp->pt.y);
  117.         ptmp->oval = val;
  118.         ptmp++;
  119.     }
  120.     break;
  121.     case VERTICAL:
  122.     len = pl->next->pt.y - pl->pt.y;
  123.     width = pl->next->pt.x - pl->pt.x;
  124.     pbuf = (struct pval *) malloc(len * sizeof(struct pval));
  125.     ptmp = pbuf;
  126.     for (y = pl->pt.y; y < pl->next->pt.y; y++) {
  127.         val = 0;
  128.         for (x = pl->pt.x; x < pl->next->pt.x; x++) {
  129.         val += getpix(orig_img, x, y);
  130.         };
  131.         val = val / width;
  132.         /*
  133.          * okay we have computed an average value, lets add it to the
  134.          * point buffer.
  135.          */
  136.         ptmp->pt.x = (short) pl->pt.x + width / 2;;
  137.         ptmp->pt.y = (short) y;
  138.         ptmp->val = XGetPixel(orig_ximg, ptmp->pt.x, ptmp->pt.y);
  139. #ifdef DEBUG
  140.         printf("(%d,%d): Local Value: %d, Averaged Value: %d\n", (int) ptmp->pt.x,
  141.          (int) ptmp->pt.y, getpix(orig_img, ptmp->pt.x, ptmp->pt.y),
  142.            val);
  143. #endif
  144.         ptmp->oval = val;
  145.         ptmp++;
  146.     };
  147.     break;
  148.     /* no default case */
  149.     }
  150.     *obuf = pbuf;
  151.     return len;
  152. }
  153.  
  154. /* getpix() -- return the gray value for a pixel given an original image */
  155. unsigned long
  156. getpix(img, x, y)
  157.     struct img_data *img;
  158.     unsigned long x, y;
  159. {
  160.     return dval(x, y, img, 0);
  161. }
  162.  
  163.  
  164. int
  165. slope(dl)
  166.     struct dlist *dl;
  167. {
  168.     double    x1, y1, x2, y2;
  169.  
  170.     x1 = (double) dl->points[0].pt.x;
  171.     y1 = (double) dl->points[0].pt.y;
  172.     x2 = (double) dl->points[dl->len - 1].pt.x;
  173.     y2 = (double) dl->points[dl->len - 1].pt.y;
  174.     return irint((y2 - y1) / (x2 - x1));
  175. }
  176.  
  177. double
  178. distance(pt1, pt2)
  179.     XPoint    pt1, pt2;
  180. {
  181.     register double x1, y1, x2, y2, dsq;
  182.  
  183.     x1 = (double) pt1.x;
  184.     y1 = (double) pt1.y;
  185.     x2 = (double) pt2.x;
  186.     y2 = (double) pt2.y;
  187.  
  188.     dsq = ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  189.     return (sqrt(dsq));
  190. }
  191.  
  192. double
  193. idist(a, b, a2, b2)
  194.     int       a, b, a2, b2;
  195. {
  196.     register double x1, y1, x2, y2, dsq;
  197.  
  198.     x1 = (double) a;
  199.     y1 = (double) b;
  200.     x2 = (double) a2;
  201.     y2 = (double) b2;
  202.  
  203.     dsq = ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  204.     return (sqrt(dsq));
  205. }
  206.  
  207. /* routines for adding and deleting elements from a linked list */
  208.  
  209. /* llist_add -- add an element to the end of a linked list */
  210. llist_add(ele, head, tail)
  211.     llist    *ele, **head, **tail;
  212. {
  213.     llist    *trav;
  214.  
  215.     if (*head == NULL) {
  216.     *head = ele;
  217.     (*head)->next = NULL;
  218.     (*head)->prev = NULL;
  219.     if (tail != NULL) {
  220.         (*tail) = *head;
  221.     }
  222.     return;
  223.     }
  224.     /* there is at least one element */
  225.     for (trav = *head; trav->next != NULL; trav = trav->next) {
  226.     }
  227.     trav->next = ele;
  228.     ele->prev = trav;
  229.     ele->next = NULL;
  230.     if (tail != NULL) {
  231.     *tail = ele;
  232.     }
  233. }
  234.  
  235. /* llist_del() -- delete a given entry from a linked list */
  236. llist_del(ent, head, tail)
  237.     llist    *ent, **head, **tail;
  238. {
  239.     llist    *trav;
  240.  
  241.     trav = ent;
  242.     if (trav == *head) {
  243. #ifdef WHY_DID_ANTONY_DO_THIS
  244.     /* it could be the tail also! */
  245.     if (tail != NULL)
  246.         if (trav == *tail)
  247.         *tail = NULL;
  248. #endif
  249.     *head = trav->next;
  250.     if (trav->next != NULL)
  251.         trav->next->prev = NULL;
  252.     free(trav);
  253.     } else {
  254.     /* not the head, but is it the tail? */
  255.     if (trav == *tail) {
  256.         *tail = (trav->prev);
  257.         if (trav->prev != NULL)
  258.         trav->prev->next = NULL;
  259.         free(trav);
  260.     } else {
  261.         /* an element in the middle */
  262.         trav->prev->next = trav->next;
  263.         trav->next->prev = trav->prev;
  264.         free(trav);
  265.     }
  266.     }
  267.  
  268. }
  269.  
  270. /* llist_free() -- free every element in a linked list */
  271. llist_free(head)
  272.     llist   **head;
  273. {
  274.     llist    *trav, *tmp;
  275.  
  276.     if (*head == NULL)
  277.        return;
  278.  
  279.     if ((*head)->prev != NULL) {
  280.     (*head)->prev->next = NULL;
  281.     }
  282.     /* traverse to list end */
  283.     for (trav = tmp = *head; trav != NULL; trav = trav->next, tmp = trav) {
  284.     free(tmp);
  285.     };
  286.     *head = NULL;
  287. }
  288.  
  289. /* llist_depth() -- length of a linked list */
  290. llist_depth(head)
  291.     llist    *head;
  292. {
  293.     llist    *trav;
  294.     int       len = 0;
  295.  
  296.     for (trav = head; trav != NULL; trav = trav->next)
  297.     len++;
  298.  
  299.     return len;
  300. }
  301.  
  302. /* llist_tail() -- find the tail in a linked list */
  303. llist
  304. * llist_tail(head)
  305.     llist    *head;
  306. {
  307.     llist    *trav;
  308.  
  309.     trav = head;
  310.     if (trav->next == NULL)
  311.     return trav;
  312.     else
  313.     while (trav->next != NULL)
  314.         trav = trav->next;
  315.     return trav;
  316. }
  317.  
  318.  
  319. unsigned long
  320. dval(x, y, img, avgrad)
  321.     int       x, y;
  322.     struct img_data *img;
  323.     int       avgrad;        /* number of points to average around the x,y
  324.                  * value */
  325. {
  326.     register int xlen, ylen;
  327.     register u_long sum = 0, cnt = 0;
  328.     int       i, j;
  329.  
  330.     if (avgrad == 0) {
  331.     switch (img->dsize) {
  332.     case 1:
  333.         return (unsigned long) *((unsigned char *) paddr(x, y, img));
  334.     case 2:
  335.         return (unsigned long) *((unsigned short *) paddr(x, y, img));
  336.     case 4:
  337.         return (unsigned long) *((unsigned int *) paddr(x, y, img));
  338.     }
  339.     }
  340.     xlen = x + avgrad;
  341.     ylen = y + avgrad;
  342.  
  343.     for (i = (x - avgrad); i <= xlen; i++) {
  344.     for (j = (y - avgrad); j <= ylen; j++) {
  345.         switch (img->dsize) {
  346.         case 1:
  347.         sum += (unsigned long) *((unsigned char *) paddr(i, j, img));
  348.         break;
  349.         case 2:
  350.         sum += (unsigned long) *((unsigned short *) paddr(i, j, img));
  351.         break;
  352.         case 4:
  353.         sum += (unsigned long) *((unsigned int *) paddr(i, j, img));
  354.         break;
  355.         }
  356.         cnt++;
  357.     }
  358.     }
  359.     return sum / cnt;
  360. }
  361.  
  362.  
  363. /* routine to find the first occurence of string s2 in s1 */
  364. char     *
  365. fstring(s1, s2)
  366.     char     *s1, *s2;
  367. {
  368.     char     *tmp;
  369.  
  370.     tmp = index(s1, *s2);
  371.     while (tmp != NULL) {
  372.     if (strncmp(tmp, s2, strlen(s2)) == 0) {
  373.         return tmp;
  374.     } else {
  375.         tmp = index((char *) tmp + 1, *s2);
  376.     }
  377.     }
  378.     return tmp;
  379. }
  380.  
  381. /* read a hex string and return a single byte */
  382. u_char
  383. readhex(str)
  384.     char     *str;
  385. {
  386.     register u_char val = 0;
  387.  
  388.     if (isdigit(*str))
  389.     val = (*str - '0') * 16;
  390.     else {
  391.     if (islower(*str))
  392.         val = (*str - 'a' + 10) * 16;
  393.     }
  394.     str++;
  395.     if (isdigit(*str))
  396.     val += (*str - '0');
  397.     else {
  398.     if (islower(*str))
  399.         val += (*str - 'a' + 10);
  400.     }
  401. #ifdef DEBUG
  402.     printf("readhex: %d\n", (int) val);
  403. #endif
  404.     return val;
  405. }
  406.  
  407. /* routine to test whether or not a point is within the bounds of an XImage */
  408. /* returna 1 if true, 0 if false */
  409. int
  410. pt_in_xim(x, y, xim)
  411.     int       x, y;
  412.     XImage   *xim;
  413. {
  414.     if ((x < 0) || (y < 0)) {    /* negative #s AIGH! */
  415.     return 0;
  416.     }
  417.     if ((x >= xim->width) || (y >= xim->height))
  418.     return 0;
  419.     return 1;
  420. }
  421.